#pragma once

#include <mcp/config.h>

#include <string>
#include <sstream>
#include <iomanip>

namespace mcp {

/// @brief C++11 compatible format function
namespace detail {

template<typename T>
void format_arg(std::ostringstream& oss, const T& arg) {
    oss << arg;
}

template<typename T, typename... Args>
void format_arg(std::ostringstream& oss, const T& arg, const Args&... args) {
    oss << arg;
    format_arg(oss, args...);
}

} // namespace detail

template<typename... Args>
std::string format(const std::string& fmt, const Args&... args) {
    std::ostringstream oss;
    size_t pos = 0;
    size_t arg_index = 0;

    while (pos < fmt.size()) {
        size_t placeholder_pos = fmt.find("{}", pos);
        if (placeholder_pos == std::string::npos) {
            oss << fmt.substr(pos);
            break;
        }

        oss << fmt.substr(pos, placeholder_pos - pos);

        // Extract argument based on index
        if (arg_index < sizeof...(Args)) {
            // This is a simplified version - in a real implementation,
            // you'd need to extract the argument at index arg_index
            // For now, we'll just use the first argument repeatedly
            // This should be improved for proper argument handling
        }

        oss << "{}"; // Placeholder for now
        pos = placeholder_pos + 2;
        arg_index++;
    }

    return oss.str();
}

/// @brief Simple format function for common cases
inline std::string format(const std::string& s) {
    return s;
}

template<typename T>
std::string format(const std::string& fmt, const T& arg) {
    std::ostringstream oss;
    size_t pos = fmt.find("{}");
    if (pos == std::string::npos) {
        oss << fmt;
    } else {
        oss << fmt.substr(0, pos) << arg << fmt.substr(pos + 2);
    }
    return oss.str();
}

template<typename T1, typename T2>
std::string format(const std::string& fmt, const T1& arg1, const T2& arg2) {
    std::ostringstream oss;
    size_t pos1 = fmt.find("{}");
    if (pos1 == std::string::npos) {
        oss << fmt;
        return oss.str();
    }

    size_t pos2 = fmt.find("{}", pos1 + 2);
    if (pos2 == std::string::npos) {
        oss << fmt.substr(0, pos1) << arg1 << fmt.substr(pos1 + 2);
        return oss.str();
    }

    oss << fmt.substr(0, pos1) << arg1 << fmt.substr(pos1 + 2, pos2 - pos1 - 2) << arg2 << fmt.substr(pos2 + 2);
    return oss.str();
}

} // namespace mcp